use snafu::Snafu;
use uuid::Uuid;

use super::Blueprint;
use crate::core::error::blueprint_error::BlueprintError;
use crate::core::error::ParrotError;
use crate::core::operation::{cmd::Cmd, git::Git};
use crate::core::services::job::job::{Job, JobBuilder};
use crate::core::util::Util;

#[derive(Debug, Snafu)]
#[snafu(visibility(pub(crate)))]
pub enum Error {}

impl From<Error> for BlueprintError {
    fn from(value: Error) -> Self {
        BlueprintError::BuildBlog { source: value }
    }
}

#[derive(Default)]
pub struct BuildBlog {
    url: String,
    dst: String,
}

impl BuildBlog {
    pub fn new(url: &str, dst: &str) -> Result<Self, Error> {
        Ok(BuildBlog {
            url: url.to_string(),
            dst: String::from(dst),
        })
    }
}

impl Blueprint for BuildBlog {
    fn build(&self, id: usize) -> Result<Job, BlueprintError> {
        let name = Util::get_git_repo_name(&self.url).unwrap_or(Uuid::new_v4().to_string());
        let repo_path = crate::core::path_type::TypedPath::Contextual(name.to_string());
        let args = vec!["-av", "--delete", "-e", "ssh", "public/*", &self.dst];

        let job = JobBuilder::new(id)
            .add_step(Git::new(&self.url, &repo_path, "main"))
            .add_step(Cmd::new(
                "hugo",
                &repo_path,
                vec!["--cleanDestinationDir"].into_iter(),
            ))
            .add_step(Cmd::new("rsync", &repo_path, args.into_iter()))
            .build();

        Ok(job)
    }
}
